package com.wandian.texas;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.wandian.texas.entity.UserInfoEntity;
import com.wandian.util.Log;
import com.wandian.xml.RoomConfigItem;

class Single {

}

/**
 * @author long
 * @Create 2012-10-7 下午3:21:06
 * @QQ 108232706
 * @version 1.0
 * @description UserMgr
 */
public class UserMgr {

	private static UserMgr _instance = null;

	// public DBMgr dbMgr;

	public static UserMgr I() {
		if (_instance == null) {
			syncInit();
		}
		return _instance;
	}

	private static synchronized void syncInit() {
		if (_instance == null) {
			_instance = new UserMgr(new Single());
		}
	}

	public Map<Integer, SessionObject> onlineUserMap = null;
	public ArrayList<SessionObject> onlineUserList = null;

	public UserMgr(Single single) {
		if (single == null) {
			throw new IllegalArgumentException("Can\'t create instance , Single is Null!");
		}
		onlineUserMap = new ConcurrentHashMap<Integer, SessionObject>();
		onlineUserList = new ArrayList<SessionObject>();
		// userInfoDao = new UserInfoDaoImpl(null);
		// chatDao = new ChatrecordDaoImpl(null);
	}

	public void loginOff(SessionObject session) {
		UserInfoEntity user = session.getUser();
		if (user != null) {
			this.onlineUserMap.remove(user.userId);
			this.onlineUserList.remove(session);
		}
	}

	/**
	 * 游戏服注销中心服成功
	 * 
	 * @param serverid
	 * @param session
	 */
	public void loginOff(int serverid, SessionObject session) {
		this.onlineUserMap.remove(serverid);
		this.onlineUserList.remove(session);
	}

	public void loginOn(SessionObject session) {
		if (!session.isConnect())
			return;
		UserInfoEntity user = session.getUser();
		if (user != null) {
			this.onlineUserMap.put(user.userId, session);
			this.onlineUserList.add(session);
		}
	}

	/**
	 * 游戏服连中心服成功
	 * 
	 * @param serverid
	 * @param session
	 */
	public void loginOn(int serverid, SessionObject session) {
		if (!session.isConnect())
			return;
		this.onlineUserMap.put(serverid, session);
		this.onlineUserList.add(session);
	}

	// public boolean broadCastToAllOnlines(short cmdId, ByteBuffer bytes) {
	// long t1 = System.currentTimeMillis();
	// for (int i = 0; i < onlineUserList.size(); i++) {
	// SendData(onlineUserList.get(i), cmdId, bytes);
	// }
	// long t2 = System.currentTimeMillis();
	// Log.info(String.format("[UserMgr][%s] 发送大喇叭,广播用户:%s,耗时%sms!",
	// DateUtil.format(new Date()), onlineUserList.size(), (t2 - t1)));
	// return true;
	// }

	public boolean broadCastToAllOnlines(BaseCommandObject dataPacket) {
		long t1 = System.currentTimeMillis();
		for (int i = 0; i < onlineUserList.size(); i++) {
			SendData(onlineUserList.get(i), dataPacket);
		}
//		long t2 = System.currentTimeMillis();
//		Log.debug(String.format("[UserMgr]广播用户:%s,耗时%sms!", onlineUserList.size(), (t2 - t1)));
		return true;
	}

	/**
	 * 向整个房间玩家广播
	 * 
	 * @param socketCmd
	 * @return
	 */
	public boolean broadCastToRoomUsers(BaseCommandObject socketCmd) {
		UserInfoEntity user = socketCmd.getUser();
		if (user != null) {
			ArrayList<SessionObject> roomUsers = RoomMgr.getRoom(user.roomId).roomUsers();
			if (roomUsers != null) {
				for (int i = 0; i < roomUsers.size(); i++) {
					SendData(roomUsers.get(i), socketCmd);
				}
			}
		}
		return false;

	}

	/**
	 * 向整个房间玩家广播
	 * 
	 * @param socketCmd
	 * @return
	 */
	public boolean broadCastToRoomUsers(RoomConfigItem room, BaseCommandObject dataPacket) {
		if (room != null) {
			ArrayList<SessionObject> roomUsers = room.roomUsers();
			if (roomUsers != null) {
				for (int i = 0; i < roomUsers.size(); i++) {
					SendData(roomUsers.get(i), dataPacket);
				}
			}
		}
		return false;

	}

	public boolean broadCastToRoomUsers(int roomid, BaseCommandObject dataPacket) {
		RoomConfigItem room = RoomMgr.getRoom(roomid);
		if (room == null) {
			return false;
		}
		ArrayList<SessionObject> roomUsers = room.roomUsers();
//		System.out.println("广播当前房间人:" + roomUsers.size());
		if (roomUsers != null) {
			for (int i = 0; i < roomUsers.size(); i++) {
				SendData(roomUsers.get(i), dataPacket);
			}
		}
		return false;
	}

	/**
	 * 向整个房间其他玩家广播
	 * 
	 * @param socketCmd
	 * @return
	 */
	public boolean broadCastToRoomOtherUsers(BaseCommandObject socketCmd) {
		UserInfoEntity user = socketCmd.getUser();
		if (user != null) {
			RoomMgr.getRoom(user.roomId).RoomDoorLock().lock();
			try {
				ArrayList<SessionObject> roomUsers = RoomMgr.getRoom(user.roomId).roomUsers();
				if (roomUsers != null) {
					for (int i = 0; i < roomUsers.size(); i++) {
						if (roomUsers.get(i) == socketCmd.sessionObject)
							continue;
						SendData(roomUsers.get(i), socketCmd);
					}
				}
			} finally {
				RoomMgr.getRoom(user.roomId).RoomDoorLock().unlock();
			}
		}
		return false;

	}

	// public boolean SendData(SessionObject sessionObj, short cmdId, ByteBuffer
	// bytes) {
	// bytes.position(0);
	// Log.debug(String.format("[UserMgr]========>准备发命令:%s name:%s length:%s",
	// cmdId, CommandSet.getCmdName(cmdId), bytes.remaining()));
	// synchronized (sessionObj.getSendBuffer()) {
	// ByteBuffer sendBuffer = sessionObj.getSendBuffer();
	// if (sendBuffer.remaining() < bytes.remaining()) {
	// Log.error(String.format("[UserMgr]用户[%s]的发送缓冲已经不足,消息长度[%s]，请检查!",
	// sessionObj, bytes.remaining()));
	// return false;
	// }
	// sendBuffer.putInt(29099);
	// sendBuffer.putInt(bytes.remaining() + 22);// length
	// sendBuffer.putShort(cmdId);// cmd
	// sendBuffer.putInt(1);// temp1
	// sendBuffer.putInt(2);// temp2
	// sendBuffer.putInt(3);// temp3
	// sendBuffer.put(bytes);
	// sessionObj.getHasSendData().set(true);
	//
	// }
	// return true;
	// }

	public boolean SendData(SessionObject sessionObj, BaseCommandObject dataPacket) {
		if (dataPacket.getCmd() < 1) {
			Log.error("cmdid error");
			return false;
		}
		dataPacket.position(0);
		SocketChannel channel = sessionObj.getChannel();
		if (sessionObj.sessionKey == null) {
			return false;
		}
		synchronized (channel) {
			ByteBuffer sendBuffer = sessionObj.getSendBuffer();
			if (sendBuffer.remaining() < dataPacket.remaining() + 22) {
//				Log.error(String.format("[UserMgr]用户[%s]的发送缓冲已经不足,消息长度[%s]，请检查!", sessionObj, dataPacket.remaining()));
				return false;
			}
			sendBuffer.putInt(29099);
			sendBuffer.putInt(dataPacket.remaining() + 22);// length
			sendBuffer.putShort(dataPacket.getCmd());// cmd
			sendBuffer.putInt(1);// temp1
			sendBuffer.putInt(2);// temp2
			sendBuffer.putInt(3);// temp3
			sendBuffer.put(dataPacket.getBytes());
			sendBuffer.flip();
			while (sessionObj.sessionKey != null&&sendBuffer.remaining() > 0) {
				try {
					channel.write(sendBuffer);
				} catch (IOException e) {
					e.printStackTrace();
					Log.info(e);
				}
			}
			sendBuffer.compact();
		}
		return true;
	}

	public boolean SendData0(SessionObject sessionObj, BaseCommandObject dataPacket) {
		if (dataPacket.getCmd() < 1) {
			Log.error("cmdid error");
			return false;
		}
		dataPacket.position(0);
//		Log.debug(String.format("[UserMgr]========>准备发命令:%s name:%s length:%s bytes[%s]", dataPacket.getCmd(), CommandSet.getCmdName(dataPacket.getCmd()), dataPacket.remaining(), "..."));
		synchronized (sessionObj.getSendBuffer()) {
			ByteBuffer sendBuffer = sessionObj.getSendBuffer();
			if (sendBuffer.remaining() < dataPacket.remaining() + 22) {
//				Log.error(String.format("[UserMgr]用户[%s]的发送缓冲已经不足,消息长度[%s]，请检查!", sessionObj, dataPacket.remaining()));
				return false;
			}
			sendBuffer.putInt(29099);
			sendBuffer.putInt(dataPacket.remaining() + 22);// length
			sendBuffer.putShort(dataPacket.getCmd());// cmd
			sendBuffer.putInt(1);// temp1
			sendBuffer.putInt(2);// temp2
			sendBuffer.putInt(3);// temp3
			sendBuffer.put(dataPacket.getBytes());
			sessionObj.getHasSendData().set(true);

		}
		return true;
	}

	public boolean SendData(BaseCommandObject socketCmd) {
		return this.SendData(socketCmd.sessionObject, socketCmd);
	}

	/**
	 * 将数据以16进制展现
	 * 
	 * @return
	 */
//	public String byteToHex(ByteBuffer byteBuffer) {
//		if (byteBuffer == null)
//			return "";
//		StringBuilder tempStr = new StringBuilder("[");
//		int oldpositon = byteBuffer.position();
//		String value;
//		while (byteBuffer.remaining() > 0) {
//			value = Integer.toHexString(byteBuffer.get() & 0xFF);
//			tempStr.append(value.length() > 1 ? value : String.format("0%s", value)).append(",");
//		}
//		tempStr.append("]");
//		byteBuffer.position(oldpositon);
//		return tempStr.toString().toUpperCase();
//	}
}
